package com.jrx.anytxn.param.job.paph.config;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.param.config.AnytxnBatchProperties;
import com.jrx.anytxn.param.config.PaphConfig;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.RepayResult;
import com.jrx.anytxn.param.entity.TlFilePaymentLog;
import com.jrx.anytxn.param.job.paph.step.RepayResultProcessor;
import com.jrx.anytxn.param.job.paph.step.RepayResultWriter;
import com.jrx.anytxn.param.mapper.ext.ExtTlFilePaymentLogMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.validation.BindException;

import java.io.*;
import java.util.Arrays;
import java.util.List;

/**
 * 正常还款文件job
 */
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
public class ReadRepayFileConfiguration {
    @Autowired
    public PaphConfig paphConfig;
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private RepayResultProcessor repayResultProcessor;
    @Autowired
    private RepayResultWriter repayResultWriter;
    @Autowired
    private ExtTlFilePaymentLogMapper extTlFilePaymentLogMapper;
    @Autowired
    private AnytxnBatchProperties anytxnBatchProperties;

    @Bean
    public Job readRepayFileJob() {
        return jobBuilderFactory.get("readRepayFileJob")
                .start(readRepayFileStep())
                .build();
    }


    @Bean
    public Step readRepayFileStep() {
        return stepBuilderFactory.get("readRepayFileStep")
                .listener(repayStepListener())
                .<RepayResult, TlFilePaymentLog>chunk(anytxnBatchProperties.getRepayResultConfig().getChunkLimit())
                .reader(repayMultiFileReader())
                .processor(repayResultProcessor)
                .writer(repayResultWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchProperties.getRepayResultConfig().getThrottleLimit())
                .build();
    }


    @StepScope
    @Bean
    public MultiResourceItemReader<RepayResult> repayMultiFileReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.DEFAULT_ORG_NUMBER);
        String fileDate = DateUtils.format(org.getNextProcessingDate(), "yyyyMMdd");
        String toDay = DateUtils.format(org.getNextProcessingDate(), "yyyyMMdd");
        // 经营贷路径
        String jyFilePath = paphConfig.getRepayResultFilePath()+ org.getTenantId() + File.separator + toDay + File.separator + Constant.PRODECUT_TYPE_JY + File.separator;
        // 消费贷路径
        String xfFilePath = paphConfig.getRepayResultFilePath()+ org.getTenantId() + File.separator + toDay + File.separator + Constant.PRODECUT_TYPE_XF + File.separator;
        String jyFileName = jyFilePath + Constant.LS_BANK+Constant.PRODECUT_TYPE_JY+ fileDate + Constant.SERVICE_TYPE + ".txt";
        String xfFileName = xfFilePath + Constant.LS_BANK+Constant.PRODECUT_TYPE_XF+ fileDate + Constant.SERVICE_TYPE + ".txt";
        MultiResourceItemReader<RepayResult> reader = new MultiResourceItemReader<>();
        reader.setDelegate(repayFlatFileReader());
        File fileJY = new File(jyFileName);
        File fileXf= new File(xfFileName);
        Resource[] resources = new Resource[2];
        resources[0] = new FileSystemResource(fileJY);
        resources[1] = new FileSystemResource(fileXf);
        reader.setResources(resources);
        return reader;
    }

    private StepExecutionListener repayStepListener() {
        return new RepayStepListener();
    }

    @StepScope
    @Bean
    public FlatFileItemReader<RepayResult> repayFlatFileReader() {

        FlatFileItemReader<RepayResult> reader = new FlatFileItemReader<>();

        //跳过第一行
        reader.setComments(new String[]{"H|", "F|"});
        //解析数据
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer("|");
        tokenizer.setNames("line","loanNo", "tradeDate", "tradeAmt", "tradeSeqNo", "tradeFlag", "acctFlag");
        //把解析出的一行数据映射为RepayResult
        DefaultLineMapper<RepayResult> mapper = new DefaultLineMapper<>();
        mapper.setLineTokenizer(tokenizer);
        mapper.setFieldSetMapper(new FieldSetMapper<RepayResult>() {
            @Override
            public RepayResult mapFieldSet(FieldSet fieldSet) throws BindException {
                RepayResult repayResult = new RepayResult();
                repayResult.setLoanNo(fieldSet.readString("loanNo"));
                repayResult.setTradeDate(fieldSet.readString("tradeDate"));
                repayResult.setTradeAmt(fieldSet.readBigDecimal("tradeAmt"));
                repayResult.setTradeSeqNo(fieldSet.readString("tradeSeqNo"));
                repayResult.setTradeFlag(fieldSet.readString("tradeFlag"));
                repayResult.setAcctFlag(fieldSet.readString("acctFlag"));
                return repayResult;
            }
        });
        mapper.afterPropertiesSet();
        reader.setLineMapper(mapper);
        return reader;
    }

    public class RepayStepListener extends StepExecutionListenerSupport {
        @Override
        public void beforeStep(StepExecution stepExecution) {
            super.beforeStep(stepExecution);
            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.DEFAULT_ORG_NUMBER);
            List<String> item = Arrays.asList(Constant.DuePay_PAYMENT,Constant.DEL_PAYMENT);
            extTlFilePaymentLogMapper.batchDeleteBydate(org.getNextProcessingDate(),item);
        }
    }


}
